home *** CD-ROM | disk | FTP | other *** search
- /*
- * Assign Command - C Language Equivalent.
- *
- * This command looks and feels like the original AmigaDOS Assign command
- * except that it is written in C and thus available for "forking." Also
- * since it is written in C it is a somewhat larger than it's BCPL counterpart
- * although a good assembly hack could probably fix that.
- *
- * (c) Copyright 1986 Charles McManis, All rights reserved.
- * This code may be copied for private use only. It may not be
- * included as part of any commercial package in whole or in
- * part without the express written permission of the Author.
- *
- */
-
- #include <exec/types.h>
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #include <libraries/filehandler.h>
- #include <stdio.h>
-
- extern struct DosLibrary *DOSBase;
-
- #define PATHSIZE 128 /* This is max numbers in a path (Arbitrary) */
- struct DosInfo *di;
- struct FileInfoBlock *fi; /* Our file info (on directory assigns) */
- char *pathstr, *tmpstr;
-
- /*
- * Function - MyExit(ConditionCode)
- * This is the final exit routine, if we can't find something we need
- * like memory we go here and free up what we have. Exit code is 'cc'.
- */
- void MyExit(cc)
-
- int cc;
-
- {
- if (fi != NULL) FreeMem(fi,sizeof(struct FileInfoBlock));
- if (pathstr != NULL) FreeMem(pathstr,PATHSIZE);
- if (tmpstr != NULL) FreeMem(tmpstr,PATHSIZE);
- exit(cc);
- }
-
- /*
- * Function - CvtBstr(str)
- * This function takes a BPTR to a BSTR and returns a pointer to an
- * equivalent C string that may be printed or copied.
- */
-
- #define STRSIZE 81
-
- char *
- CvtBstr(bstr)
-
- char *bstr;
-
- {
- int i,mx;
- char *foo;
- static char tmpstr[STRSIZE]; /* Maximum size */
-
- foo = (char *)(BADDR(bstr));
- mx = (foo[0] < STRSIZE) ? foo[0] : STRSIZE; /* Safety net */
- for (i=0; i<mx; i++) tmpstr[i] = foo[i+1];
- tmpstr[i] = '\0';
- return(tmpstr);
- }
-
- /*
- * Function - DeleteDevice(Name)
- * This function will search the device list for a directory entry
- * matching the one passed, and remove it from the device list.
- *
- * Returns 0 if successful.
- */
-
- int
- DeleteDevice(nm)
-
- char *nm; /* String pointer to the Name */
-
- {
- struct DeviceList *prevdev,*thisdev;
- char *str;
- int i,found;
-
- prevdev = NULL;
- thisdev = (struct DeviceList *)BADDR(di->di_DevInfo);
- found = -1;
- while (thisdev != NULL) {
- if (thisdev->dl_Type == DLT_DIRECTORY) {
- str = CvtBstr(thisdev->dl_Name);
- if (stricmp(str,nm) == 0) {
- found = 0;
- if (prevdev == NULL) { /* If first device */
- Forbid(); /* Turn off tasking */
- di->di_DevInfo = thisdev->dl_Next; /* Delete from list */
- Permit(); /* Turn tasking back on */
- }
- else {
- Forbid(); /* Turn off tasking */
- prevdev->dl_Next = thisdev->dl_Next; /* Delete from list */
- Permit(); /* Back to multitasking */
- }
- /* Now free the Lock, the String, and the DevList structure */
- UnLock(thisdev->dl_Lock); /* free the lock */
- str = (char *)(BADDR(thisdev->dl_Name)); /* easier to read */
- i = str[0];
- FreeMem(str,i); /* Free the string */
- FreeMem(thisdev,sizeof(struct DeviceList)); /* Free struct */
- break; /* Exit the while loop */
- } /* if matched devices */
- } /* if it was a directory entry */
- prevdev = thisdev; /* If not found, walk the list */
- thisdev = (struct DeviceList *)BADDR(thisdev->dl_Next);
- } /* While */
- return(found);
- }
-
- /*
- * Main code, options of the Assign command are name, directory, or List.
- * the default is to list the current assignments, Volumes, and devices.
- *
- */
-
- void main(argc,argv)
-
- int argc; /* Number of arguments (max 3) */
- char *argv[]; /* Text of the arguments */
-
- {
- /* The pointers here make it easier later */
-
- struct RootNode *rn;
- struct DeviceList *dl, *curdev, *xl;
- struct DeviceNode *dn;
- struct FileLock *fl;
- BPTR plock, thislock, tb;
- char Name[41],Path[81],*sptr;
- int i,listem;
-
- /* Get some memory for various buffers */
- fi = (struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock),0);
- if (fi == NULL) MyExit(RETURN_FAIL);
- pathstr = (char *)AllocMem(PATHSIZE,0);
- if (pathstr == NULL) MyExit(RETURN_FAIL);
- tmpstr = (char *)AllocMem(PATHSIZE,0);
- if (tmpstr == NULL) MyExit(RETURN_FAIL);
-
- printf("Assign command substitute v1.0\n");
- /* Then we track down the head of the Device list from the Root Node */
- rn = (struct RootNode *)DOSBase->dl_Root;
- di = (struct DosInfo *)BADDR(rn->rn_Info);
- /* dl becomes the anchor point that we always start from */
- dl = (struct DeviceList *)BADDR(di->di_DevInfo);
- listem = FALSE; /* Initially no list output */
- Name[0] = '\0'; /* No name parameter */
- Path[0] = '\0'; /* And no path specifier */
-
- /*************************************************************************
- * Process the arguments passed. To be 100% compatible with the AmigaDOS *
- * assign command. *
- *************************************************************************/
-
- if (argc > 4) {
- printf("Too many arguments, usage is Assign [Name:] [Dir:] [List]\n");
- MyExit(RETURN_WARN);
- }
- for (i=1; i<argc; i++)
- if (stricmp(argv[i],"LIST") == 0) listem = TRUE;
- else if (Name[0] == '\0') strcpy(Name,argv[i]);
- else if (Path[0] == '\0') strcpy(Path,argv[i]);
- else {
- printf("Bad Arguments, usage is Assign [Name:] [Dir:] [List]\n");
- MyExit(RETURN_WARN);
- }
- if (strcmp(Name,"?") == 0) {
- printf("Usage is Assign [Name:] [Dir:] [List]\n");
- MyExit(RETURN_OK);
- }
- if (argc > 1) {
- if ((sptr = (char *)strchr(Name,':')) == NULL) {
- printf("Improper device name format.\n");
- MyExit(RETURN_WARN);
- }
- *sptr = '\0'; /* Eliminate the trailing colon */
- }
- /* Ok, now we have the parameters they work like this, if a name was
- * supplied but no path then it is a deassign operation, if both are
- * supplied it is an assign operation, if both are missing it is a
- * list operation
- */
- if ((Name[0] != '\0') && (Path[0] == '\0')) /* DEASSIGN 'Name' */
- if (DeleteDevice(Name) != 0) {
- printf("Device %s: Not found.\n");
- MyExit(RETURN_WARN);
- }
- if ((Name[0] != '\0') && (Path[0] != '\0')) { /* ASSIGN 'Name' */
- (void) DeleteDevice(Name); /* Delete in case it exists */
- if ((thislock = Lock(Path,ACCESS_READ)) != 0) {
- dl = (struct DeviceList *)AllocMem(sizeof(struct DeviceList),0);
- sptr = (char *)AllocMem(strlen(Name)+1,0);
- strcpy(sptr+1,Name); /* Create BSTR out of Name */
- *sptr = strlen(Name);
- dl->dl_Name = (BSTR *)(((long)sptr) >> 2); /* Convert to BSTR ptr */
- dl->dl_Lock = thislock; /* Put the BPTR value into Lock */
- dl->dl_Type = DLT_DIRECTORY; /* The type is Directory */
- fl = (struct FileLock *)(BADDR(thislock)); /* for convience */
- dl->dl_Task = fl->fl_Task; /* Copy the message port task ptr */
- tb = (BPTR)(((long)dl) >> 2); /* Make a BPTR out of our pointer */
- Forbid(); /* Disable multitasking */
- dl->dl_Next = di->di_DevInfo; /* Insert it at the head */
- di->di_DevInfo = tb; /* Put a pointer to us in DevInfo */
- Permit(); /* Start up Multitasking again */
- } /* if we got the lock */
- else {
- printf("Couldn't get a Lock on %s\n",Path);
- MyExit(RETURN_WARN);
- }
- } /* ASSIGN operation */
- if (((Name[0] != '\0') || (Path[0] != '\0')) && ! listem) MyExit(RETURN_OK);
-
- /* The remainder of the code lists out the current assignments, if
- * no arguments, or the argument "List" is included it will run this
- * section.
- *
- * Pass 1: Print out all of the known volumes, if they have a handler
- * task present then they are mounted in a physical device
- */
- curdev = dl;
- printf("Volumes:\n");
- while (curdev != NULL) {
- if (curdev->dl_Type == DLT_VOLUME) {
- printf("%s ",CvtBstr(curdev->dl_Name));
- if (curdev->dl_Task != NULL) printf("[Mounted]");
- printf("\n");
- }
- curdev = (struct DeviceList *)BADDR(curdev -> dl_Next);
- }
- printf("\n");
-
- /* Pass 2 : Scan for directory redirections. If the volume that the
- * directory is redirected to is not mounted then we just
- * print out the volume name. If it is mounted we print
- * out the full path. If we have been redirected to a device
- * like 'RAM' then we just print the device name.
- */
- curdev = dl;
- printf("Directories:\n");
- while (curdev != NULL) {
- if (curdev->dl_Type == DLT_DIRECTORY) {
- strcpy(tmpstr,CvtBstr(curdev->dl_Name));
- printf("%s ",tmpstr);
- if (strlen(tmpstr) < 8) printf(" ");
- fl = (struct FileLock *)(BADDR(curdev->dl_Lock));
- xl = (struct DeviceList *)(BADDR(fl->fl_Volume));
- if (xl->dl_Type == DLT_DEVICE) {
- dn = (struct DeviceNode *) xl;
- printf("%s:",CvtBstr(dn->dn_Name));
- }
- else {
- if (xl->dl_Task == NULL) /* Not Mounted if Task == NULL */
- printf("Volume: %s",CvtBstr(xl->dl_Name));
- else { /* This code tracks down the full path */
- printf("%s:",CvtBstr(xl->dl_Name));
- pathstr[0] = '\0'; /* initialize it to the null string */
- thislock = curdev->dl_Lock;
- plock = ParentDir(thislock);
- while (plock != 0) {
- if (Examine(thislock,fi)) {
- if (strlen(pathstr) == 0) strcpy(pathstr,fi->fib_FileName);
- else {
- strins(pathstr,"/"); /* insert directory separator */
- strins(pathstr,fi->fib_FileName); /* insert parent dir name */
- }
- }
- else printf("\nBad Lock!\n"); /* This should never print! */
- thislock = plock;
- plock = ParentDir(thislock);
- } /* while we haven't got to the top */
- printf("%s",pathstr);
- }
- } /* else it was a directory rather than a device */
- printf("\n");
- } /* If it was a directory redirection at all */
- curdev = (struct DeviceList *)BADDR(curdev -> dl_Next);
- }
- printf("\n");
-
- /* Pass 3 : Print out all of the devices, like the original we pretty much
- * assume device names are three characters long. (They can be more
- * though.)
- */
- printf("Devices:");
- i = 0;
- curdev = dl;
- while (curdev != NULL) {
- if (curdev->dl_Type == DLT_DEVICE) {
- if ((i%5) == 0) printf("\n"); /* Every 5 devices print a newline */
- i++;
- dn = (struct DeviceNode *) curdev;
- printf("%s ",CvtBstr(dn->dn_Name));
- }
- curdev = (struct DeviceList *)BADDR(curdev -> dl_Next);
- } /* While */
- printf("\n");
- MyExit(RETURN_OK); /* Exit with a status of zero */
- }
-